<template>
  <view class="user-info-edit f fd-col ai-c">
    <view class="user-info-edit__edit-part f fd-col">
      <van-skeleton
        avatar
        :row="6"
        :loading="skeletonLoading"
        avatar-size="160rpx"
        class="f1"
        style="margin-top: 0"
      >
        <view class="user-about f ai-c"
          ><view class="head-portrait-upload f fd-col ai-c">
            <van-uploader
              v-model="fileList"
              :max-count="1"
              :preview-full-image="!isAvatarLoadingError"
              :after-read="afterRead"
              image-fit="cover"
              @click-preview="clickPreview"
            />
          </view>
          <view class="user-info f1">
            <view class="name" :style="[formData.userName ? {} : emptyName]">{{
              formData.userName || "请输入用户名"
            }}</view>
            <view class="phone">{{ formData.userPhone }}</view>
          </view></view
        >
        <view class="edit">
          <uni-forms ref="form" :rules="rules" :modelValue="formData">
            <uni-forms-item label="用户名" name="userName" required
              ><uni-easyinput
                v-model="formData.userName"
                :inputBorder="false"
                placeholder="请输入用户名"
            /></uni-forms-item>
            <uni-forms-item label="手机号" name="userPhone" required
              ><uni-easyinput
                v-model="formData.userPhone"
                :inputBorder="false"
                placeholder="请输入手机号"
            /></uni-forms-item>
            <uni-forms-item label="密码" name="userPwd" required
              ><uni-easyinput
                v-model="formData.userPwd"
                :inputBorder="false"
                placeholder="请输入密码"
                type="password"
            /></uni-forms-item>
            <uni-forms-item label="请再次输入密码" name="userPwdR" required
              ><uni-easyinput
                v-model="formData.userPwdR"
                :inputBorder="false"
                placeholder="请再次输入密码"
                type="password"
            /></uni-forms-item>
          </uni-forms>
        </view>
      </van-skeleton>
    </view>
    <view class="button-part f jc-c ai-c">
      <van-button
        type="primary"
        style="width: 90%"
        round
        loading-type="spinner"
        loading-text="修改中"
        @click="userInfoEdit"
        :disabled="skeletonLoading || disabled"
        :loading="loading"
        >确认修改</van-button
      >
    </view>
  </view>
</template>

<script>
import { ref, reactive, watchEffect, computed } from "vue";
import { ImagePreview } from "vant";
import loginAPI from "/api/modules/login";
import profileAPI from "/api/modules/profile";
import {
  getValueFromUrl,
  image_loading_error_base64_data,
  applyUniWebViewSDK,
} from "/utils/index";
export default {
  name: "user-info-edit",
  setup() {
    applyUniWebViewSDK();
    const href = window.location.href;
    const userName = ref(getValueFromUrl(href, "userName"));
    const userPhone = ref(getValueFromUrl(href, "userPhone"));
    const userPwd = ref(getValueFromUrl(href, "userPwd"));
    const form = ref(null);
    const loading = ref(false);
    const skeletonLoading = ref(true);
    const isAvatarLoadingError = ref(false);
    const fileList = ref([]);
    const oldFileList = ref([]);
    const editStatus = ref(0);
    const emptyName = reactive({
      color: "red",
    });
    let formData = reactive({
      userName: "",
      userPhone: "",
      userPwd: "",
      userPwdR: "",
    });
    let oldFormData = reactive({});
    const disabled = computed(
      () =>
        formData.userName === "" ||
        formData.userPhone === "" ||
        formData.userPwd === "" ||
        formData.userPwdR === ""
    );
    const rules = {
      userName: { rules: [{ required: true, errorMessage: "姓名不能为空" }] },
      userPhone: {
        rules: [
          { required: true, errorMessage: "手机号不能为空" },
          {
            validateFunction: (rule, value, data, callback) => {
              // 异步需要返回 Promise 对象
              return new Promise((resolve, reject) => {
                const reg = /^1[3|4|5|7|8]\d{9}$/;
                setTimeout(() => {
                  if (reg.test(value)) {
                    // 通过返回 resolve
                    resolve();
                  } else {
                    // 不通过返回 reject(new Error('错误信息'))
                    reject(new Error("手机号码格式错误!"));
                  }
                }, 0);
              });
            },
          },
        ],
      },
      userPwd: { rules: [{ required: true, errorMessage: "密码不能为空" }] },
      userPwdR: {
        rules: [
          {
            required: true,
            errorMessage: "前后设置密码不一致",
          },
          {
            validateFunction: (rule, value, data, callback) => {
              // 异步需要返回 Promise 对象
              return new Promise((resolve, reject) => {
                setTimeout(() => {
                  if (value === formData.userPwd) {
                    // 通过返回 resolve
                    resolve();
                  } else {
                    // 不通过返回 reject(new Error('错误信息'))
                    reject(new Error("前后设置密码不一致!"));
                  }
                }, 0);
              });
            },
          },
        ],
        validateTrigger: "bind",
      },
    };
    const toastMessage = [
      "修改成功，请重新登录",
      "修改失败,请稍后重试",
      "更新头像成功",
      "无效修改，表单和头像没有变化",
    ];
    const getAvatar = () => {
      const params = {
        userName: userName.value,
        userPhone: userPhone.value,
      };
      profileAPI
        .getAvatar(params)
        .then((res) => {
          fileList.value = [
            {
              content: "data:image/png;base64," + res,
            },
          ];
          oldFileList.value = [
            {
              content: "data:image/png;base64," + res,
            },
          ];
        })
        .catch((err) => {
          console.log(err);
          fileList.value = [
            {
              content: image_loading_error_base64_data,
            },
          ];
          oldFileList.value = [
            {
              content: image_loading_error_base64_data,
            },
          ];
          isAvatarLoadingError.value = true;
          uni.showToast({
            title: "用户头像加载失败",
            duration: 1000,
            icon: "none",
            position: "top",
          });
        });
    };
    const getUseInfo = async () => {
      uni.showLoading({
        title: "加载中",
      });
      // 获取用户头像
      await getAvatar();
      oldFormData.userName = userName.value;
      oldFormData.userPhone = userPhone.value;
      oldFormData.userPwd = userPwd.value;
      oldFormData.userPwdR = userPwd.value;
      loginAPI
        .loginQuery({
          userName: userName.value,
          userPhone: userPhone.value,
          userPwd: userPwd.value,
        })
        .then((res) => {
          formData.userName = res[0].userName;
          formData.userPhone = res[0].userPhone;
          formData.userPwd = res[0].userPwd;
          formData.userPwdR = res[0].userPwd;
          skeletonLoading.value = false;
        })
        .catch((err) => {
          console.log(err);
          skeletonLoading.value = true;
        })
        .finally(() => {
          uni.hideLoading();
        });
    };
    const userInfoEdit = () => {
      form.value
        .validate()
        .then(async (res) => {
          loading.value = true;
          const infoParams = {
            newUserName: formData.userName,
            newUserPhone: formData.userPhone,
            newUserPwd: formData.userPwd,
            oldUserName: oldFormData.userName,
            oldUserPhone: oldFormData.userPhone,
            oldUserPwd: oldFormData.userPwd,
          };
          const avatarParams = {
            userName: formData.userName,
            userPhone: formData.userPhone,
            content: fileList.value.length > 0 ? fileList.value[0].content : "",
          };
          // 判断修改前后表单数据是否一致
          const isSameFormData = Object.keys(formData).every(
            (item) => formData[item] === oldFormData[item]
          );
          // 判断修改前后头像是否一致
          const isSameAvatar =
            fileList.value[0].content === oldFileList.value[0].content;
          // 1.表单数据和头像修改前后都不一致--->先更新表单再更新头像，退出登录
          // 2.表单数据修改前后不一致但头像修改前后一致--->先更新表单在更新头像，退出登录
          // promise.all是并发同时执行的，then回调打印的数组是实际执行顺序
          if (
            (!isSameFormData && !isSameAvatar) ||
            (!isSameFormData && isSameAvatar)
          ) {
            // 定义上传表单和上传头像的状态
            let upLoadFormDataStatus, upLoadAvatarStatus;
            await profileAPI
              .updateUserInfo(infoParams)
              .then((res) => {
                upLoadFormDataStatus = true;
                // 更新oldFormData
                oldFormData = Object.assign({}, formData);
                // 发送事件让webView页面缓存
                // h5无效，app有效
                uni.webView.postMessage({
                  data: {
                    fromH5: true,
                    userName: formData.userName,
                    userPhone: formData.userPhone,
                    msg: "更新userName和userPhone,删除loginStatus",
                  },
                });
              })
              .catch((err) => {
                console.log("更新表单失败");
                upLoadFormDataStatus = false;
                console.log(err);
              });
            await profileAPI
              .uploadAvatar(avatarParams)
              .then((res) => {
                // 更新oldFileList
                oldFileList.value[0] = Object.assign({}, fileList.value[0]);
                upLoadAvatarStatus = true;
              })
              .catch((err) => {
                upLoadAvatarStatus = false;
                console.log(err);
              })
              .finally(() => {
                loading.value = false;
              });
            if (upLoadFormDataStatus && upLoadAvatarStatus) {
              // 都更新成功
              // 1.表单数据和头像修改前后一致2.表单修改前后不一致但头像修改前后一致
              editStatus.value = 0;
              // 退出登录
              setTimeout(() => {
                uni.webView.navigateTo({
                  url: "/pages/login/login",
                });
              }, 2000);
            } else if (!upLoadFormDataStatus || !upLoadAvatarStatus) {
              // 任何一个更新失败
              editStatus.value = 1;
            }
          } else if (isSameFormData && !isSameAvatar) {
            // 3.表单数据修改前后一致，头像修改前后不一致--->只更新头像，不退出登录
            await profileAPI
              .uploadAvatar(avatarParams)
              .then((res) => {
                // 更新oldFileList
                oldFileList.value[0] = Object.assign({}, fileList.value[0]);
                // 修改toast信息
                editStatus.value = 2;
              })
              .catch((err) => {
                editStatus.value = 1;
                console.log(err);
              })
              .finally(() => {
                loading.value = false;
              });
          } else if (isSameFormData && isSameAvatar) {
            // 4.表单数据和头像修改前后都一致--->啥都不干
            editStatus.value = 3;
            loading.value = false;
          }
          // 展示toast
          uni.showToast({
            title: toastMessage[editStatus.value],
            icon: "none",
            duration: 2000,
            position: "top",
          });
        })
        .catch((err) => {
          console.log("表单错误信息：", err);
        });
    };
    const clickPreview = (file) => {
      console.log('快打印吧',!isAvatarLoadingError.value);
      if (!isAvatarLoadingError.value) {
        ImagePreview([file.content]);
      }
    };
    const afterRead = () => {
      isAvatarLoadingError.value = false;
    };
    watchEffect(() => {
      getUseInfo();
    });
    return {
      fileList,
      form,
      loading,
      skeletonLoading,
      isAvatarLoadingError,
      editStatus,
      disabled,
      rules,
      emptyName,
      formData,
      userInfoEdit,
      clickPreview,
      afterRead,
    };
  },
};
</script>
<style lang='scss' scoped>
.user-info-edit {
  position: relative;
  width: 100%;
  height: 100vh;
  background-color: #f2f3f7;
  &__edit-part {
    padding: 20rpx;
    width: 100%;
    height: 100%;
    box-sizing: border-box;
    background-color: #fff;
    ::v-deep .van-skeleton {
      margin-top: 20rpx;
      padding: 0;
      .van-skeleton__row {
        margin-top: 40rpx;
        width: 510rpx !important;
        &:first-child {
          margin-top: 10rpx;
        }
        &:nth-child(n + 3) {
          margin-top: 90rpx;
          margin-left: -180rpx;
          width: 690rpx !important;
        }
      }
    }
    .user-about {
      margin-bottom: 50rpx;
      .head-portrait-upload {
        margin-right: 20rpx;
        ::v-deep .van-uploader__preview {
          margin: 0;
        }
        ::v-deep .van-uploader__upload {
          margin: 0;
          border-radius: 50%;
        }
        ::v-deep .van-uploader__preview-image {
          border-radius: 50%;
        }
      }
      .user-info {
        margin-left: 34rpx;
        padding: 30rpx;
        font-size: 40rpx;
        .phone {
          margin-top: 50rpx;
          font-size: 30rpx;
        }
      }
    }
    .edit {
      ::v-deep .uni-forms-item {
        .uni-forms-item__label {
          width: 240rpx !important;
          .label-text {
            font-size: 30rpx !important;
          }
        }
        .uni-forms-item__content {
          border-bottom: 1px solid #ddd;
          .uni-input-placeholder {
            font-size: 30rpx !important;
          }
          .uni-input-input {
            font-size: 30rpx !important;
          }
        }
        .uni-error-message {
          padding-left: 240rpx !important;
        }
      }
    }
  }
  .button-part {
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;
    height: 180rpx;
    background-color: #fff;
    box-shadow: 0 -2px 4px #eee;
  }
}
</style>